{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Improved Integration of GRASS and Jupyter\n",
    "\n",
    "As part of Google Summer of Code 2021, we've been working to shorten and simplify the launch of GRASS in Jupyter and imporve the map displays. You can find out more about the project and follow the progress on the [GRASS wiki page](https://trac.osgeo.org/grass/wiki/GSoC/2021/JupyterAndGRASS).\n",
    "\n",
    "This notebook is designed to run in binder and demonstrate the usage of `grass.jupyter`, the new module of Jupyter-specific functions for GRASS."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import subprocess\n",
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gisbase = subprocess.check_output([\"grass\", \"--config\", \"path\"], text=True).strip()\n",
    "os.environ[\"GISBASE\"] = gisbase\n",
    "sys.path.append(os.path.join(gisbase, \"etc\", \"python\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import grass.script as gs\n",
    "import grass.jupyter as gj"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Start GRASS Session\n",
    "gj.init(\"../../data/grassdata\", \"nc_basic_spm_grass7\", \"user1\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set computational region to the study area.\n",
    "gs.run_command(\"g.region\", raster=\"elevation\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Non-interactive Map Display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Demonstration of GrassRenderer for non-interactive map display\n",
    "r = gj.GrassRenderer(height=540)\n",
    "\n",
    "# Add a raster and vector to the map\n",
    "r.run(\"d.rast\", map=\"elevation\")\n",
    "r.run(\"d.vect\", map=\"streams\")\n",
    "\n",
    "# We can also call 'd.*' display modules with a shortcut\n",
    "# Shortcut methods must be in the form '.d_{name_of_module}'\n",
    "# For example, let's add a legend using a shortcut\n",
    "r.d_legend(raster=\"elevation\", at=(55, 95, 2, 6), flags=\"b\") # shortcut for calling \"d.legend\"\n",
    "\n",
    "# Display map\n",
    "r.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Multiple instances of GrassRenderer\n",
    "\n",
    "We can have multiple instances of GrassRenderer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# First, we'll make a second instance. Notice we need a different filename.\n",
    "\n",
    "r2 = gj.GrassRenderer(height=200, width=220, filename =\"roads_maps.png\")\n",
    "\n",
    "r2.run(\"d.rast\", map=\"elevation_shade\")\n",
    "r2.run(\"d.vect\", map=\"roadsmajor\")\n",
    "\n",
    "r2.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Then, we return to the first instance and continue to modify and display it\n",
    "# Notice that layers a drawn in the order they are added\n",
    "\n",
    "r.run(\"d.vect\", map = \"zipcodes\", color=\"red\", fill_color=\"none\")\n",
    "\n",
    "r.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Interactive Map Display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Interactive Map\n",
    "m = gj.InteractiveMap(width = 600)\n",
    "\n",
    "# Add raster, vector and layer control to map\n",
    "m.add_raster(\"elevation\")\n",
    "m.add_vector(\"roadsmajor\")\n",
    "m.add_layer_control(position = \"bottomright\")\n",
    "\n",
    "# Display map\n",
    "m.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's see what is in the example database so we can continue to experiment\n",
    "print(gs.read_command(\"g.list\", type=\"all\"))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
